﻿namespace dogd
{
	using System.Data;
	using System.Data.Common;
	using System.Data.SQLite;
	using System;

	/// <summary>
	/// Connection provider specific to Sqlite.
	/// </summary>
	public class SqliteConnectionProvider : IConnectionProvider
	{
		/// <summary>
		/// Constructor using a given path.
		/// </summary>
		/// <param name="path">The path to the database file.</param>
		public SqliteConnectionProvider(string path)
		{
			this.Path = path;
		}

		/// <summary>
		/// Use an in-memory instance
		/// </summary>
		public SqliteConnectionProvider()
		{
			this.Path = ":memory:";
		}

		/// <summary>
		/// Gets a connection to the sqlite database.
		/// </summary>
		public DbConnection Connection
		{
			get 
			{
				DbConnection connection = this.Factory.CreateConnection();
				connection.ConnectionString = this.ConnectionString;
				
				// if db locked - wait a moment ???
				bool retry = false;

				do
				{
					try
					{
						if (connection.State == ConnectionState.Closed)
						{
							connection.Open();
						}
						retry = false;
					}
					catch (SQLiteException)
					{
						System.Threading.Thread.Sleep(new Random((int)DateTime.Today.Ticks).Next(1000));
						retry = true;
					}
				} while (retry);

				return connection;
			}
		}

		private string Path { get; set; }

		private string ConnectionString
		{
			get
			{
				return string.Format("Data Source={0}", 
					this.Path, 
					System.Globalization.CultureInfo.InvariantCulture);
			}
		}

		private DbProviderFactory Factory
		{
			get
			{
				return SQLiteFactory.Instance; // DbProviderFactories.GetFactory("System.Data.SQLite");
			}
		}
	}
}
